package com.xuecheng.manage_media_process.mq;

import com.alibaba.fastjson.JSON;
import com.xuecheng.framework.domain.media.MediaFile;
import com.xuecheng.framework.domain.media.MediaFileProcess_m3u8;
import com.xuecheng.framework.utils.HlsVideoUtil;
import com.xuecheng.framework.utils.Mp4VideoUtil;
import com.xuecheng.manage_media_process.dao.MediaFileRepository;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Optional;

//监听mq
@Component
public class MediaProcessTask {
    @Autowired
    MediaFileRepository mediaFileRepository;

    //从yml注入ffmpeg软件的位置
    @Value("${xc-service-manage-media.ffmpeg-path}")
    String ffmpeg_path;

    //从yml注入:上传文件根目录
    @Value("${xc-service-manage-media.video-location}")
    String serverPath;



    /**
     * 监听队列,从yml文件中获取队列名称
     * @param msg   从队列中拿到信息
     */
    @RabbitListener(queues = "${xc-service-manage-media.mq.queue-media-video-processor}",containerFactory = "customContainerFactory")
    public void receiveMediaProcessTask(String msg){
        //第一件事:解析消息内容,得到mediaId
        Map map = JSON.parseObject(msg, Map.class);
        String mediaId = (String) map.get("mediaId");
        //第二件事:从mediaId从数据库查询文件信息  --拿文件位置
        Optional<MediaFile> optional = mediaFileRepository.findById(mediaId);
        if (!optional.isPresent()){
            return;  //--这是监听,没有监听到返回就行.
        }
        MediaFile mediaFile = optional.get();
        //第三件事:使用工具类将avi文件生成MP4
        //3-1:判断文件类型是否是avi
        String fileType = mediaFile.getFileType();
        if (!fileType.equals("avi")){
            //数据词典来自 dictionary
            mediaFile.setProcessStatus("303004");//无需处理
            mediaFileRepository.save(mediaFile);
            return ;
        }else{
            //需要处理
            mediaFile.setProcessStatus("303001");//处理中
            mediaFileRepository.save(mediaFile);
        }
        //3-2:使用工具将avi文件生成mp4
        //String ffmpeg_path, String video_path, String mp4_name, String mp4folder_path
        //3-2-1:要处理的视频文件具体位置
        String video_path = serverPath + mediaFile.getFilePath() + mediaFile.getFileName();
        //生成的mp4的文件名称
        String mp4_name = mediaFile.getFileId() + ".mp4";
        //生成的mp4所在的路径
        String mp4folder_path = serverPath + mediaFile.getFilePath();
        //3-2-2:创建工具类对象
        Mp4VideoUtil mp4VideoUtil =new Mp4VideoUtil(ffmpeg_path,video_path,mp4_name,mp4folder_path);
        //进行处理
        String result = mp4VideoUtil.generateMp4();  //--返回String字符串,是因为方法定义的 可看源码
        if(result == null || !result.equals("success")){
            //处理失败
            mediaFile.setProcessStatus("303003");
            //定义mediaFileProcess_m3u8
            MediaFileProcess_m3u8 mediaFileProcess_m3u8 = new MediaFileProcess_m3u8();
            //记录失败原因
            mediaFileProcess_m3u8.setErrormsg(result);
            mediaFile.setMediaFileProcess_m3u8(mediaFileProcess_m3u8);
            mediaFileRepository.save(mediaFile);
            return ;
        }
        //第四件事:将mp4生成m3u8和ts文件
        //4-1:处理工具类所需路径
        //mp4文件路径
        String mp4_video_path = serverPath + mediaFile.getFilePath() + mp4_name;
        //m3u8_name文件名称
        String m3u8_name = mediaFile.getFileId() + ".m3u8";
        //m3u8文件所在目录
        String m3u8folder_path = serverPath +  mediaFile.getFilePath() + "his/";
        //4-2 使用工具类
        HlsVideoUtil hlsVideoUtil = new HlsVideoUtil(ffmpeg_path, mp4_video_path, m3u8_name, m3u8folder_path);
        //4-2-1 生成m3u8和ts文件
        String tsResult = hlsVideoUtil.generateM3u8();
        //4-2-2 记录执行情况到mongodb  和  记录错误信息
        if (tsResult == null ||  !tsResult.equals("sccess")){
            //处理失败结果
            mediaFile.setProcessStatus("303003");
            //定义mediaFileProcess_m3u8
            MediaFileProcess_m3u8 mediaFileProcess_m3u8 = new MediaFileProcess_m3u8();
            //记录错误信息
            mediaFileProcess_m3u8.setErrormsg(tsResult);
            mediaFile.setMediaFileProcess_m3u8(mediaFileProcess_m3u8);
            mediaFileRepository.save(mediaFile);
        }
        //第五件事:处理成功  更新mongodb中的数据  --更新处理情况*(ts列表,操作状态)
        //5-1 获取分块的ts文件
        List<String> ts_list = hlsVideoUtil.get_ts_list();
        //5-2 定义mediaFileProcess_m3u8
        MediaFileProcess_m3u8 mediaFileProcess_m3u8 = new MediaFileProcess_m3u8();
        mediaFileProcess_m3u8.setTslist(ts_list);
        mediaFile.setMediaFileProcess_m3u8(mediaFileProcess_m3u8);
        //5-3 保存fileUrl（此url就是视频播放的相对路径)  不保存根路径  目的:日后播放视频使用
        String fileUrl = mediaFile.getFilePath() + "hls/"+m3u8_name;
        mediaFile.setFileUrl(fileUrl);
        mediaFileRepository.save(mediaFile);
        //5-4
    }

}
